home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / wwindow2.arc / WINDOW.C < prev    next >
Text File  |  1986-08-11  |  10KB  |  456 lines

  1.     /*-------------------------------------*/
  2.     /*-                                    */
  3.     /*-      Window                        */
  4.     /*-                                    */
  5.     /*-                                    */
  6.     /*-------------------------------------*/
  7.  
  8. static char copyright[] = "Copyright 1986 by Nourse, Gregg & Browne Inc.";
  9. /*                (201) 886-2642 Ft. Lee NJ 07024   */
  10.  
  11. #include "dos.h"
  12.  
  13. #define HI 0x08
  14. #define WHITE '\x07'
  15. #define CR '\x0d'
  16. #define LF '\x0a'
  17. #define BS '\x08'
  18. #define FALSE '\0'
  19. #define TRUE '\x01'
  20. #define LEFT 75
  21. #define RIGHT 77
  22. #define ZIP '\0'
  23.  
  24. struct window_struct    {
  25.         int top;    /* top of window on display */
  26.         int left;    /* left side of window */
  27.         int bottom;    /* bottom of display */
  28.         int right;    /* right most screen column */
  29.         int attr;    /* character attribute for this window */
  30.         int row,col;    /* window's virtual cursor position */
  31.         char *old;    /* buffer to hold old screen contents */
  32.         char title_present; /* flag set if window has title */
  33.         };
  34.  
  35. static struct window_struct *ww[32];
  36. static int wi=1;
  37. static char dash[] = "═════════════════════════════════════════════════════";
  38. static char *left_end = "╒";
  39. static char *right_end = "╕";
  40. static int row_stack[16];
  41. static int col_stack[16];
  42. static int cur_sp = 0;
  43.  
  44.  
  45. static char *trim(ss)
  46.     char *ss;
  47.          {
  48.          int i;
  49.  
  50.          i = strlen(ss) -1;
  51.          while (ss[i]==' ' && i>=0)
  52.               {
  53.               ss[i--] = '\0';
  54.               }
  55.          return(ss);
  56.          }
  57.  
  58.  
  59. static wscroll(window,lines)
  60.     int window,lines;
  61.         {
  62.         union REGS rr;
  63.         struct window_struct *win;
  64.  
  65.         win=ww[window];
  66.         rr.h.ah=6;        /* func: scroll up */
  67.         rr.h.al=lines;        /* number of line to scroll */
  68.         rr.h.ch=win->top;    /* top left row, column */
  69.         rr.h.cl=win->left;    /* top left row, column */
  70.         rr.h.dh=win->bottom;    /* bottom row */
  71.         rr.h.dl=win->right;    /* right column */
  72.         rr.h.bh=win->attr;    /* blanking attr */
  73.         int10(&rr);
  74.             }
  75.  
  76. static char *save_area(top,left,bottom,right)
  77.     int top,left,bottom,right;
  78.     {
  79.     char *savea, *p;
  80.     int siz, row, col;
  81.     union REGS rr;
  82.  
  83.     siz = (bottom - top + 1) * (right - left + 1) * 2 ;
  84.     p=savea=(char *)malloc(siz);
  85.     if (p==NULL) return(NULL);
  86.     for (row=top;row<=bottom;row++)
  87.         {
  88.         for (col=left;col<=right;col++)
  89.             {
  90.             rr.h.ah=2;    /* func: set cursor position */
  91.             rr.h.dh=row;    /* row # */
  92.             rr.h.dl=col;    /* col # */
  93.             rr.h.bh=0;    /* page zero */
  94.             int10(&rr);
  95.             rr.h.ah=8;    /* func: read char */
  96.             rr.h.bh=0;    /* page zero */
  97.             int10(&rr);    /* read it */
  98.             *p++=rr.h.al;    /* save the character */
  99.             *p++=rr.h.ah;    /* save the attribute */
  100.             }
  101.         }
  102.     return(savea);
  103.     }
  104.  
  105. static restore_area(win)
  106.     int win;
  107.     {
  108.     int top, bottom, left, right;
  109.     char *p;
  110.     int row, col;
  111.     union REGS rr;
  112.  
  113.     p=ww[win]->old;
  114.     if (p==NULL) return;
  115.     top=ww[win]->top;
  116.     bottom=ww[win]->bottom;
  117.     left=ww[win]->left;
  118.     right=ww[win]->right;
  119.     if (ww[win]->title_present) top-- ;
  120.     for (row=top;row<=bottom;row++)
  121.         {
  122.         for (col=left;col<=right;col++)
  123.             {
  124.             rr.h.ah=2;    /* func: set cursor position */
  125.             rr.h.dh=row;    /* row # */
  126.             rr.h.dl=col;    /* col # */
  127.             rr.h.bh=0;    /* page zero */
  128.             int10(&rr);
  129.             rr.h.ah=9;    /* func: write char + attr */
  130.             rr.h.bh=0;    /* page zero */
  131.             rr.x.cx=1;    /* count */
  132.             rr.h.al=*p++;    /* the character */
  133.             rr.h.bl=*p++;    /* the attribute */
  134.             int10(&rr);    /* write it */
  135.             }
  136.         }
  137.     free(ww[win]->old);
  138.     ww[win]->old=NULL;
  139.     }
  140.  
  141.  
  142.  
  143. static setpos(win)
  144.     int win;
  145.     {
  146.     union REGS rr;
  147.  
  148.     if (ww[win]->col > ww[win]->right)
  149.         {
  150.         ww[win]->col=ww[win]->left;
  151.         ww[win]->row++;
  152.         }
  153.     if (ww[win]->row > ww[win]->bottom)
  154.         {
  155.         wscroll(win,1);
  156.         ww[win]->row=ww[win]->bottom;
  157.         }
  158.     rr.h.ah=2;        /* func: set cursor position */
  159.     rr.h.dh=ww[win]->row;    /* row */
  160.     rr.h.dl=ww[win]->col;    /* column */
  161.     rr.h.bh=0;        /* page zero */
  162.     int10(&rr);
  163.     }
  164.  
  165. static readpos(win)
  166.     int win;
  167.     {
  168.     union REGS rr;
  169.  
  170.     rr.h.ah=3;        /* func: read cursor position */
  171.     rr.h.bh=0;        /* page zero */
  172.     int10(&rr);        /* video int */
  173.     ww[win]->row=rr.h.dh;
  174.     ww[win]->col=rr.h.dl;
  175.     }
  176.  
  177.  
  178.  
  179. static save_cursor()
  180.     {
  181.     union REGS rr;
  182.  
  183.     rr.h.ah=3;        /* func: read cursor position */
  184.     rr.h.bh=0;        /* page zero */
  185.     int10(&rr);        /* video int */
  186.     cur_sp++;        /* push */
  187.     row_stack[cur_sp]=rr.h.dh; /* row */
  188.     col_stack[cur_sp]=rr.h.dl;  /* col */
  189.     }
  190.  
  191. static restore_cursor()
  192.     {
  193.     union REGS rr;
  194.  
  195.     rr.h.dh=row_stack[cur_sp];
  196.     rr.h.dl=col_stack[cur_sp];
  197.     cur_sp--;        /* pop */
  198.     rr.h.ah=2;        /* func: set cursor position */
  199.     rr.h.bh=0;        /* page zero */
  200.     int10(&rr);
  201.     }
  202.  
  203.  
  204. static wputc(win,c)
  205.     int win;
  206.     char c;
  207.     {
  208.     union REGS rr;
  209.  
  210.     switch (c)
  211.         {
  212.         case CR:
  213.             {
  214.             ww[win]->col=ww[win]->left;
  215.             break;
  216.             }
  217.         case LF:
  218.             {
  219.             if (ww[win]->row < ww[win]->bottom) ww[win]->row++;
  220.              else
  221.                  {
  222.                  wscroll(win,1);
  223.                  ww[win]->row=ww[win]->bottom;
  224.                  }
  225.             break;
  226.             }
  227.         case BS:
  228.             {
  229.             if (ww[win]->col > ww[win]->left) ww[win]->col--;
  230.             break;
  231.             }
  232.         default:
  233.             {
  234.             setpos(win);
  235.             rr.h.ah=9;    /* func: write char and attr */
  236.             rr.h.bh=0;    /* page zero */
  237.             rr.x.cx=1;    /* one character */
  238.             rr.h.al=c;    /* the byte */
  239.             rr.h.bl=ww[win]->attr; /* the char's attribute */
  240.             int10(&rr);
  241.             ww[win]->col++;
  242.             break;
  243.             }
  244.         }
  245.     }
  246.  
  247. static wblank(win,len)
  248.     int win, len;
  249.     {
  250.     int r,c, i;
  251.  
  252.     r=ww[win]->row;
  253.     c=ww[win]->col;
  254.     for (i=0;i<len;i++) wputc(win,' ');
  255.     ww[win]->row=r;
  256.     ww[win]->col=c;
  257.     }
  258.  
  259.  
  260. static char wgetc(win)
  261.     int win;
  262.     {
  263.     union REGS rr;
  264.  
  265.     setpos(win);
  266.     rr.h.ah=8;        /* func: read char */
  267.     rr.h.bh=0;        /* page zero */
  268.     int10(&rr);        /* video INT */
  269.     ww[win]->col++;
  270.     return(rr.h.al);    /* the character */
  271.     }
  272.  
  273.  
  274. void wprint(window_handle,text)    /* print a string at window's cursor */
  275.     int window_handle;    /* the handle from wopen() */
  276.     char *text;        /* the string to print */
  277.     {
  278.     char *p;
  279.  
  280.     save_cursor();
  281.     for (p=text;(*p!='\0');p++)
  282.         {
  283.         wputc(window_handle,*p);
  284.         }
  285.     restore_cursor();
  286.     }
  287.  
  288.  
  289.  
  290. int wopen(top,left,bottom,right,attr,title) /* returns 'window handle' */
  291.     int    top,    /* top row of window */
  292.         left,    /* left side column */
  293.         bottom,    /* bottom row of window */
  294.         right,    /* right side column */
  295.         attr;    /* the screen attribute for this window */
  296.     char *title;    /* NULL or the title for the window (optional) */
  297.     {
  298.     int i, l, width, title_len, x;
  299.     struct window_struct *win = NULL;
  300.  
  301.     for (i=1;i<wi;i++) { if (ww[i]==NULL) break; }
  302.     if (i==wi) wi++;
  303.     win=(struct window_struct *)malloc(sizeof(struct window_struct));
  304.     if (win==NULL) return(-1);
  305.     win->top=top;
  306.     win->left=left;
  307.     win->bottom=bottom;
  308.     win->right=right;
  309.     win->attr=attr;
  310.     win->col=left;
  311.     win->row=bottom;
  312.     win->title_present=FALSE;
  313.     ww[i]=win;
  314.     save_cursor();
  315.     win->old=save_area(top,left,bottom,right);
  316.     wscroll(i,0);
  317.     if (title!=NULL)
  318.         {
  319.         win->title_present=TRUE;
  320.         win->row=top;
  321.         win->attr=attr | WHITE ;
  322.         title_len=strlen(title) + 6;
  323.         width=(win->right - win->left)+1;
  324.         l=(width - title_len) / 2;
  325.         x=strlen(dash) - l;
  326.         wprint(i,left_end);
  327.         wprint(i,&dash[x]);
  328.         wprint(i,"╡ ");
  329.         win->attr=attr | WHITE | HI;
  330.         wprint(i,title);
  331.         win->attr=attr | WHITE ;
  332.         wprint(i," ╞");
  333.         l=(width - title_len) - l;
  334.         x=strlen(dash) - l;
  335.         wprint(i,&dash[x]);
  336.         wprint(i,right_end);
  337.         win->attr=attr;
  338.         win->col=left;
  339.         win->row=bottom;
  340.         win->top++;
  341.         }
  342.     restore_cursor();
  343.     return(i);
  344.     }
  345.  
  346.  
  347. void wclose(window_handle) /* close the window, restore prior screen */
  348.     int window_handle;    /* handle you got from wopen() */
  349.     {
  350.     save_cursor();
  351.     restore_area(window_handle);
  352.     free(ww[window_handle]);
  353.     ww[window_handle]=NULL;
  354.     restore_cursor();
  355.     }
  356.  
  357.  
  358. void wlocate(window_handle,row,col) /* move cursor relative to origin */
  359.     int    window_handle,    /* the handle from wopen() */
  360.         row,        /*  the relative row (from 0) */
  361.         col;        /*  the relative column (from 0) */
  362.     {
  363.     ww[window_handle]->row=ww[window_handle]->top  + row;
  364.     ww[window_handle]->col=ww[window_handle]->left + col;
  365.     }
  366.  
  367. void wsay(window_handle,row,col,text)    /* move corsor + print text */
  368.     int    window_handle,    /* the handle from wopen() */
  369.         row,        /* row to move cursor to */
  370.         col;        /* columne to move cursor to */
  371.     char *text;        /* text to print at that location */
  372.     {
  373.     wlocate(window_handle,row,col);
  374.     wprint(window_handle,text);
  375.     }
  376.  
  377.  
  378. void winput(window_handle,row,col,field,len) /* input text from window */
  379.     int    window_handle,    /* handle from wopen() */
  380.         row,    /* row to input from */
  381.         col,    /* column to input from */
  382.         len;    /* max length of input field */
  383.     char *field;    /* default read from, and input put into here */
  384.     {
  385.     int first, last, i;
  386.     char c, s, *p;
  387.     union REGS rr;
  388.  
  389.     save_cursor();
  390.     wlocate(window_handle,row,col);
  391.     wprint(window_handle,field);
  392.     wblank(window_handle,len-strlen(field));
  393.     wlocate(window_handle,row,col);
  394.     first=ww[window_handle]->col;
  395.     last=first+len-1;
  396.     for (c=ZIP;c!=CR;)
  397.         {
  398.         setpos(window_handle);
  399.         rr.h.ah=0;
  400.         int86(0x16,&rr,&rr);
  401.         c=rr.h.al;
  402.         s=rr.h.ah;
  403.         if (c >= ' ')
  404.             {
  405.             wputc(window_handle,c);
  406.             }
  407.         switch (s)
  408.             {
  409.             case RIGHT: ww[window_handle]->col++; break;
  410.             case LEFT:  ww[window_handle]->col--; break;
  411.             default: break;
  412.             }
  413.         if (ww[window_handle]->col > last) ww[window_handle]->col=last;
  414.         if (ww[window_handle]->col < first) ww[window_handle]->col=first;
  415.         }
  416.     wlocate(window_handle,row,col);
  417.     for (p=field,i=0;i<len;p++,i++)    *p=wgetc(window_handle);
  418.     *p=ZIP;
  419.     trim(field);
  420.     restore_cursor();
  421.     }
  422.  
  423. int wselect(window_handle,row,col,field,list) /* select from a list */
  424.     int window_handle,    /* handle from wopen() */
  425.         row,col;    /* window relative position */
  426.     char    *field,        /* copy of selection put here */
  427.         *list[];    /* vector of strings of selections */
  428.     {
  429.     int i, len, maxlen;
  430.     char c, s;
  431.     union REGS rr;
  432.  
  433.     save_cursor();
  434.     for (i=0,maxlen=0;list[i]!=NULL;i++)
  435.         {
  436.         len=strlen(list[i]);
  437.         if (len>maxlen) maxlen=len;
  438.         }
  439.     for (i=0,c=0;c!=CR;)
  440.         {
  441.         wlocate(window_handle,row,col);
  442.         wblank(window_handle,maxlen);
  443.         wprint(window_handle,list[i]);
  444.         rr.h.ah=0;
  445.         int86(0x16,&rr,&rr);
  446.         c=rr.h.al;
  447.         s=rr.h.ah;
  448.         if (s==LEFT && i>0) i--;
  449.         if (c!=CR) i++;
  450.         if (list[i]==NULL) i=0;
  451.         }
  452.     strcpy(field,list[i]);
  453.     restore_cursor();
  454.     return(i); 
  455.     }
  456.